import {
  Injectable,
  BadRequestException,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { VerificationCodeType } from './dto/auth.dto';

@Injectable()
export class VerificationCodeService {
  constructor(private prisma: PrismaService) {}

  /**
   * 生成6位数字验证码
   * 开发环境固定为888888，生产环境使用随机码
   */
  private generateCode(): string {
    // 开发环境使用固定验证码，生产环境使用随机码
    // if (process.env.NODE_ENV === 'production') {
    //   return Math.floor(100000 + Math.random() * 900000).toString();
    // }
    return '888888';
  }

  /**
   * 检查发送频率限制
   */
  private async checkRateLimit(phone: string): Promise<void> {
    const now = new Date();
    const oneMinuteAgo = new Date(now.getTime() - 60 * 1000);
    const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);

    // 检查1分钟内是否已发送
    const recentCode = await this.prisma.verificationCode.findFirst({
      where: {
        phone,
        createdAt: { gte: oneMinuteAgo },
      },
    });

    if (recentCode) {
      throw new HttpException(
        '验证码发送过于频繁，请1分钟后再试',
        HttpStatus.TOO_MANY_REQUESTS,
      );
    }

    // 检查1小时内发送次数
    const hourlyCount = await this.prisma.verificationCode.count({
      where: {
        phone,
        createdAt: { gte: oneHourAgo },
      },
    });

    if (hourlyCount >= 5) {
      throw new HttpException(
        '验证码发送次数过多，请1小时后再试',
        HttpStatus.TOO_MANY_REQUESTS,
      );
    }
  }

  /**
   * 发送验证码
   */
  async sendCode(
    phone: string,
    type: VerificationCodeType,
  ): Promise<{ message: string }> {
    // 检查频率限制
    await this.checkRateLimit(phone);

    // 生成验证码
    const code = this.generateCode();
    const expiresAt = new Date(Date.now() + 5 * 60 * 1000); // 5分钟有效期

    // 保存验证码到数据库
    await this.prisma.verificationCode.create({
      data: {
        phone,
        code,
        type,
        expiresAt,
      },
    });

    // TODO: 调用短信服务发送验证码
    // 这里模拟发送成功，实际项目中需要集成真实的短信服务
    if (process.env.NODE_ENV === 'production') {
      console.log(`向 ${phone} 发送验证码: ${code}`);
    } else {
      console.log(`[开发环境] 向 ${phone} 发送验证码: ${code}`);
      console.log(`[开发环境] 验证码固定为: 888888`);
    }

    return { message: '验证码发送成功' };
  }

  /**
   * 验证验证码
   */
  async verifyCode(
    phone: string,
    code: string,
    type: VerificationCodeType,
  ): Promise<boolean> {
    const verificationCode = await this.prisma.verificationCode.findFirst({
      where: {
        phone,
        code,
        type,
        isUsed: false,
        expiresAt: { gt: new Date() },
      },
    });

    if (!verificationCode) {
      throw new BadRequestException('验证码无效或已过期');
    }

    // 标记验证码为已使用
    await this.prisma.verificationCode.update({
      where: { id: verificationCode.id },
      data: { isUsed: true },
    });

    return true;
  }

  /**
   * 清理过期验证码
   */
  async cleanupExpiredCodes(): Promise<void> {
    await this.prisma.verificationCode.deleteMany({
      where: {
        expiresAt: { lt: new Date() },
      },
    });
  }
}
